#pragma once

/*\
 *
 * Array of 256 macros to call n-repeated versions of ASM "nop" instruction
 * Used when MALLOC_CAP_EXEC cannot.
 *
 * Using templates and macros as function generators is just a lazy way so spare
 * this document from being cluttered with 512 lines of dense and redundant code.
 *
 *
\*/


// recursive repeat
template <size_t N> inline void nop_pad()
{
  nop_pad<N-1>();
  asm volatile ("nop");
}
// zero nop case
template <> inline void nop_pad<0>()  { }

// shorthand macro for function generation
#define nop(opnum) void IRAM_ATTR op##opnum(){nop_pad<opnum>();}

nop(0x00) nop(0x01) nop(0x02) nop(0x03) nop(0x04) nop(0x05) nop(0x06) nop(0x07) nop(0x08) nop(0x09) nop(0x0a) nop(0x0b) nop(0x0c) nop(0x0d) nop(0x0e) nop(0x0f)
nop(0x10) nop(0x11) nop(0x12) nop(0x13) nop(0x14) nop(0x15) nop(0x16) nop(0x17) nop(0x18) nop(0x19) nop(0x1a) nop(0x1b) nop(0x1c) nop(0x1d) nop(0x1e) nop(0x1f)
nop(0x20) nop(0x21) nop(0x22) nop(0x23) nop(0x24) nop(0x25) nop(0x26) nop(0x27) nop(0x28) nop(0x29) nop(0x2a) nop(0x2b) nop(0x2c) nop(0x2d) nop(0x2e) nop(0x2f)
nop(0x30) nop(0x31) nop(0x32) nop(0x33) nop(0x34) nop(0x35) nop(0x36) nop(0x37) nop(0x38) nop(0x39) nop(0x3a) nop(0x3b) nop(0x3c) nop(0x3d) nop(0x3e) nop(0x3f)
nop(0x40) nop(0x41) nop(0x42) nop(0x43) nop(0x44) nop(0x45) nop(0x46) nop(0x47) nop(0x48) nop(0x49) nop(0x4a) nop(0x4b) nop(0x4c) nop(0x4d) nop(0x4e) nop(0x4f)
nop(0x50) nop(0x51) nop(0x52) nop(0x53) nop(0x54) nop(0x55) nop(0x56) nop(0x57) nop(0x58) nop(0x59) nop(0x5a) nop(0x5b) nop(0x5c) nop(0x5d) nop(0x5e) nop(0x5f)
nop(0x60) nop(0x61) nop(0x62) nop(0x63) nop(0x64) nop(0x65) nop(0x66) nop(0x67) nop(0x68) nop(0x69) nop(0x6a) nop(0x6b) nop(0x6c) nop(0x6d) nop(0x6e) nop(0x6f)
nop(0x70) nop(0x71) nop(0x72) nop(0x73) nop(0x74) nop(0x75) nop(0x76) nop(0x77) nop(0x78) nop(0x79) nop(0x7a) nop(0x7b) nop(0x7c) nop(0x7d) nop(0x7e) nop(0x7f)
nop(0x80) nop(0x81) nop(0x82) nop(0x83) nop(0x84) nop(0x85) nop(0x86) nop(0x87) nop(0x88) nop(0x89) nop(0x8a) nop(0x8b) nop(0x8c) nop(0x8d) nop(0x8e) nop(0x8f)
nop(0x90) nop(0x91) nop(0x92) nop(0x93) nop(0x94) nop(0x95) nop(0x96) nop(0x97) nop(0x98) nop(0x99) nop(0x9a) nop(0x9b) nop(0x9c) nop(0x9d) nop(0x9e) nop(0x9f)
nop(0xa0) nop(0xa1) nop(0xa2) nop(0xa3) nop(0xa4) nop(0xa5) nop(0xa6) nop(0xa7) nop(0xa8) nop(0xa9) nop(0xaa) nop(0xab) nop(0xac) nop(0xad) nop(0xae) nop(0xaf)
nop(0xb0) nop(0xb1) nop(0xb2) nop(0xb3) nop(0xb4) nop(0xb5) nop(0xb6) nop(0xb7) nop(0xb8) nop(0xb9) nop(0xba) nop(0xbb) nop(0xbc) nop(0xbd) nop(0xbe) nop(0xbf)
nop(0xc0) nop(0xc1) nop(0xc2) nop(0xc3) nop(0xc4) nop(0xc5) nop(0xc6) nop(0xc7) nop(0xc8) nop(0xc9) nop(0xca) nop(0xcb) nop(0xcc) nop(0xcd) nop(0xce) nop(0xcf)
nop(0xd0) nop(0xd1) nop(0xd2) nop(0xd3) nop(0xd4) nop(0xd5) nop(0xd6) nop(0xd7) nop(0xd8) nop(0xd9) nop(0xda) nop(0xdb) nop(0xdc) nop(0xdd) nop(0xde) nop(0xdf)
nop(0xe0) nop(0xe1) nop(0xe2) nop(0xe3) nop(0xe4) nop(0xe5) nop(0xe6) nop(0xe7) nop(0xe8) nop(0xe9) nop(0xea) nop(0xeb) nop(0xec) nop(0xed) nop(0xee) nop(0xef)
nop(0xf0) nop(0xf1) nop(0xf2) nop(0xf3) nop(0xf4) nop(0xf5) nop(0xf6) nop(0xf7) nop(0xf8) nop(0xf9) nop(0xfa) nop(0xfb) nop(0xfc) nop(0xfd) nop(0xfe) nop(0xff)


typedef void (*CpuDelay_t)();
CpuDelay_t nops[256] =
{
  &op0x00, &op0x01, &op0x02, &op0x03, &op0x04, &op0x05, &op0x06, &op0x07, &op0x08, &op0x09, &op0x0a, &op0x0b, &op0x0c, &op0x0d, &op0x0e, &op0x0f,
  &op0x10, &op0x11, &op0x12, &op0x13, &op0x14, &op0x15, &op0x16, &op0x17, &op0x18, &op0x19, &op0x1a, &op0x1b, &op0x1c, &op0x1d, &op0x1e, &op0x1f,
  &op0x20, &op0x21, &op0x22, &op0x23, &op0x24, &op0x25, &op0x26, &op0x27, &op0x28, &op0x29, &op0x2a, &op0x2b, &op0x2c, &op0x2d, &op0x2e, &op0x2f,
  &op0x30, &op0x31, &op0x32, &op0x33, &op0x34, &op0x35, &op0x36, &op0x37, &op0x38, &op0x39, &op0x3a, &op0x3b, &op0x3c, &op0x3d, &op0x3e, &op0x3f,
  &op0x40, &op0x41, &op0x42, &op0x43, &op0x44, &op0x45, &op0x46, &op0x47, &op0x48, &op0x49, &op0x4a, &op0x4b, &op0x4c, &op0x4d, &op0x4e, &op0x4f,
  &op0x50, &op0x51, &op0x52, &op0x53, &op0x54, &op0x55, &op0x56, &op0x57, &op0x58, &op0x59, &op0x5a, &op0x5b, &op0x5c, &op0x5d, &op0x5e, &op0x5f,
  &op0x60, &op0x61, &op0x62, &op0x63, &op0x64, &op0x65, &op0x66, &op0x67, &op0x68, &op0x69, &op0x6a, &op0x6b, &op0x6c, &op0x6d, &op0x6e, &op0x6f,
  &op0x70, &op0x71, &op0x72, &op0x73, &op0x74, &op0x75, &op0x76, &op0x77, &op0x78, &op0x79, &op0x7a, &op0x7b, &op0x7c, &op0x7d, &op0x7e, &op0x7f,
  &op0x80, &op0x81, &op0x82, &op0x83, &op0x84, &op0x85, &op0x86, &op0x87, &op0x88, &op0x89, &op0x8a, &op0x8b, &op0x8c, &op0x8d, &op0x8e, &op0x8f,
  &op0x90, &op0x91, &op0x92, &op0x93, &op0x94, &op0x95, &op0x96, &op0x97, &op0x98, &op0x99, &op0x9a, &op0x9b, &op0x9c, &op0x9d, &op0x9e, &op0x9f,
  &op0xa0, &op0xa1, &op0xa2, &op0xa3, &op0xa4, &op0xa5, &op0xa6, &op0xa7, &op0xa8, &op0xa9, &op0xaa, &op0xab, &op0xac, &op0xad, &op0xae, &op0xaf,
  &op0xb0, &op0xb1, &op0xb2, &op0xb3, &op0xb4, &op0xb5, &op0xb6, &op0xb7, &op0xb8, &op0xb9, &op0xba, &op0xbb, &op0xbc, &op0xbd, &op0xbe, &op0xbf,
  &op0xc0, &op0xc1, &op0xc2, &op0xc3, &op0xc4, &op0xc5, &op0xc6, &op0xc7, &op0xc8, &op0xc9, &op0xca, &op0xcb, &op0xcc, &op0xcd, &op0xce, &op0xcf,
  &op0xd0, &op0xd1, &op0xd2, &op0xd3, &op0xd4, &op0xd5, &op0xd6, &op0xd7, &op0xd8, &op0xd9, &op0xda, &op0xdb, &op0xdc, &op0xdd, &op0xde, &op0xdf,
  &op0xe0, &op0xe1, &op0xe2, &op0xe3, &op0xe4, &op0xe5, &op0xe6, &op0xe7, &op0xe8, &op0xe9, &op0xea, &op0xeb, &op0xec, &op0xed, &op0xee, &op0xef,
  &op0xf0, &op0xf1, &op0xf2, &op0xf3, &op0xf4, &op0xf5, &op0xf6, &op0xf7, &op0xf8, &op0xf9, &op0xfa, &op0xfb, &op0xfc, &op0xfd, &op0xfe, &op0xff,
};

/*\
 *

  // Usage:
  void nopDelay( uint8_t cycles )
  {
    nops[cycles]();
  }

\*/
